﻿// HSS.ServiceModel.Internal.MessageInspectorBindingElement.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       MessageInspectorBindingElement.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
namespace HSS.ServiceModel.Internal
{
	#region Using Directives
	using System;
	using System.ServiceModel.Channels;
	#endregion

	#region MessageInspectorBindingElement
	/// <summary>
	/// The BindingElement that allows for specifying a MessageInspector.
	/// </summary>
	[System.Diagnostics.DebuggerStepThroughAttribute()]
	internal sealed class MessageInspectorBindingElement : BindingElement
	{
		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		public MessageInspectorBindingElement()
		{
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the message inspector.
		/// </summary>
		public IMessageInspector MessageInspector { get; set; }
		#endregion

		#region Overrides
		/// <summary>
		/// Initializes a channel factory for producing channels of a specified type from the binding context.
		/// </summary>
		/// <typeparam name="TChannel">The type of channel the factory builds.</typeparam>
		/// <param name="context">The System.ServiceModel.Channels.BindingContext that provides context for the binding element.</param>
		/// <returns>The System.ServiceModel.Channels.IChannelFactory{TChannel} of type TChannel initialized from the context.</returns>
		public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
		{
			if (context == null)
				throw new ArgumentNullException("context");
			if (!this.CanBuildChannelFactory<TChannel>(context))
				throw new InvalidOperationException("Unsupported channel type");
			return new MessageInspectorChannelFactory(context.BuildInnerChannelFactory<IRequestChannel>(), MessageInspector) as IChannelFactory<TChannel>;
		}
		/// <summary>
		/// Creates deep copy of the binding element object.
		/// </summary>
		/// <returns></returns>
		public override BindingElement Clone()
		{
			return new MessageInspectorBindingElement() { MessageInspector = this.MessageInspector };
		}
		/// <summary>
		/// Returns a typed object requested, if present, from the appropriate layer in the binding stack.
		/// </summary>
		/// <typeparam name="T">The typed object for which the method is querying.</typeparam>
		/// <param name="context">The System.ServiceModel.Channels.BindingContext that provides context for the binding element.</param>
		/// <returns>The typed object T requested, if it is present or null if it is not.</returns>
		public override T GetProperty<T>(BindingContext context)
		{
			return context.GetInnerProperty<T>();
		}
		/// <summary>
		/// Returns a value that indicates whether the inner channel factory can produce a specified type of channel.
		/// </summary>
		/// <typeparam name="TChannel">The type of System.ServiceModel.Channels.IChannel object the inner channel factory produces.</typeparam>
		/// <param name="context">The System.ServiceModel.Channels.BindingContext that provides context for the binding element.</param>
		/// <returns>true if the inner channel factory can produce the specified TChannel; otherwise, false.</returns>
		public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
		{
			return context.CanBuildInnerChannelFactory<TChannel>();
		}
		#endregion
	}
	#endregion
}